03 os模块
你的代码跑在操作系统上,读写文件、创建目录、获取环境变量、执行系统命令——这些都是操作系统层面的操作。os模块就是Python提供的一套"操作系统接口",让你用Python代码来做这些事情。
os模块最大的价值是跨平台。Windows用反斜杠\,Linux/macOS用正斜杠/;Windows用nt,Linux用posix——os模块帮你抹平这些差异,一套代码到处跑。
一、环境变量
1.1 os.environ
环境变量是操作系统级别的配置,比如PATH、HOME、API_KEY等。
python
import os
# 获取所有环境变量
os.environ
# environ({'PATH': '/usr/bin', 'HOME': '/Users/apple', ...})
# 获取单个环境变量(返回字符串)
os.environ.get("HOME") # '/Users/apple'
os.environ.get("API_KEY") # None(不存在时返回None)
os.environ.get("API_KEY", "") # ''(设置默认值)
# 不存在时会抛KeyError
os.environ["NOT_EXIST"] # KeyError: 'NOT_EXIST'
# 设置环境变量(仅当前进程有效)
os.environ["API_KEY"] = "sk-xxx"
# 删除环境变量
del os.environ["API_KEY"]
# 或者用pop
os.environ.pop("API_KEY", None)1.2 os.getenv()
更简洁的获取环境变量方式。
python
import os
# 等价于os.environ.get()
api_key = os.getenv("API_KEY")
db_host = os.getenv("DB_HOST", "localhost") # 带默认值读取.env文件时,通常配合python-dotenv:
python
from dotenv import load_dotenv
import os
load_dotenv() # 加载.env文件
api_key = os.getenv("OPENAI_API_KEY")二、当前工作目录
2.1 os.getcwd()
获取当前工作目录(脚本运行时所在的目录)。
python
import os
cwd = os.getcwd()
print(f"当前目录: {cwd}")
# 当前目录: /Users/apple/project2.2 os.chdir()
切换工作目录。
python
import os
# 切换到指定目录
os.chdir("/tmp")
print(os.getcwd()) # /tmp
# 切换回上一级
os.chdir("..")注意:os.chdir()会影响整个进程,在多线程环境下要小心使用。
三、目录操作
3.1 创建目录
python
import os
# 创建单级目录
os.mkdir("logs") # 如果logs已存在,会报FileExistsError
# 创建多级目录(递归创建)
os.makedirs("data/2026/06", exist_ok=True)
# exist_ok=True:目录已存在时不报错3.2 删除目录
python
import os
# 删除空目录
os.rmdir("logs") # 目录不为空会报OSError
# 递归删除空目录
os.removedirs("data/2026/06")
# 会依次删除06、2026、data(必须都是空目录)3.3 列出目录内容
python
import os
# 列出目录下的文件和子目录
files = os.listdir(".") # 当前目录
files = os.listdir("/Users/apple") # 指定目录
# 返回的是文件名列表,不含路径
for filename in os.listdir("."):
print(filename)3.4 遍历目录树
python
import os
# os.walk()递归遍历目录
for root, dirs, files in os.walk("data"):
print(f"目录: {root}")
print(f" 子目录: {dirs}")
print(f" 文件: {files}")
print()os.walk()返回一个生成器,每个元素是(dirpath, dirnames, filenames):
dirpath:当前目录路径dirnames:子目录列表filenames:文件列表
3.5 高效目录扫描
python
import os
# os.scandir()比listdir()更高效(3.5+)
with os.scandir(".") as entries:
for entry in entries:
if entry.is_file():
print(f"文件: {entry.name}, 大小: {entry.stat().st_size}")
elif entry.is_dir():
print(f"目录: {entry.name}")os.scandir()返回DirEntry对象,可以直接获取文件类型和状态信息,不需要额外的系统调用。
四、文件操作
4.1 删除文件
python
import os
# 删除文件
os.remove("data.txt") # 文件不存在会报FileNotFoundError
# os.unlink()是os.remove()的别名
os.unlink("data.txt")
# 安全删除(先检查)
if os.path.exists("data.txt"):
os.remove("data.txt")4.2 重命名
python
import os
# 重命名文件或目录
os.rename("old.txt", "new.txt")
# 跨目录移动(也是rename)
os.rename("data.txt", "archive/data.txt")
# 目标已存在时会报错,用os.replace()可以强制覆盖
os.replace("new.txt", "old.txt")4.3 文件状态
python
import os
# 获取文件状态
stat = os.stat("data.txt")
stat.st_size # 文件大小(字节)
stat.st_mtime # 最后修改时间(时间戳)
stat.st_atime # 最后访问时间
stat.st_ctime # 创建时间(Unix)/ 元数据修改时间(Windows)
stat.st_mode # 文件模式(权限等)
# 检查文件访问权限
os.access("data.txt", os.R_OK) # 可读?
os.access("data.txt", os.W_OK) # 可写?
os.access("data.txt", os.X_OK) # 可执行?
# 修改文件权限
os.chmod("script.sh", 0o755) # 设置为可执行4.4 创建链接
python
import os
# 创建硬链接
os.link("original.txt", "hardlink.txt")
# 创建符号链接(软链接)
os.symlink("original.txt", "symlink.txt")
# 读取符号链接指向的目标
target = os.readlink("symlink.txt")五、执行系统命令
5.1 os.system()
执行系统命令,返回退出状态码。
python
import os
# 执行命令
status = os.system("ls -la")
# 0: 成功, 非0: 失败
# 注意:命令输出直接打印到终端,无法捕获5.2 os.popen()
执行命令并获取输出。
python
import os
# 获取命令输出
with os.popen("ls -la") as f:
output = f.read()
print(output)实际项目中,建议用subprocess模块,它更强大也更安全:
python
import subprocess
result = subprocess.run(["ls", "-la"], capture_output=True, text=True)
print(result.stdout)
print(result.returncode)六、路径分隔符与常量
6.1 系统常量
python
import os
# 路径分隔符
os.sep # '/' (Linux/macOS) 或 '\' (Windows)
# 行分隔符
os.linesep # '\n' (Linux/macOS) 或 '\r\n' (Windows)
# 空设备路径
os.devnull # '/dev/null' (Linux/macOS) 或 'NUL' (Windows)
# 操作系统名
os.name # 'posix' (Linux/macOS) 或 'nt' (Windows)6.2 跨平台路径拼接
python
import os
# 不要手动拼接路径(不跨平台)
path = "data" + "/" + "file.txt" # 不推荐
# 用os.path.join()(跨平台)
path = os.path.join("data", "file.txt") # 推荐七、进程信息
python
import os
# 当前进程ID
os.getpid() # 12345
# 父进程ID
os.getppid() # 12340
# 获取登录用户名
os.getlogin() # 'apple'
# 获取用户ID(Unix)
os.getuid() # 501
# 获取组ID(Unix)
os.getgid() # 20八、随机数
python
import os
# 生成密码学安全的随机字节
random_bytes = os.urandom(16)
print(random_bytes) # b'\xf3\xa1\x9c...'
# 用于生成随机整数
import struct
random_int = struct.unpack('I', os.urandom(4))[0]九、实用技巧
9.1 创建临时目录
python
import os
import tempfile
# 创建临时目录
with tempfile.TemporaryDirectory() as tmpdir:
print(f"临时目录: {tmpdir}")
# 在这里使用临时目录
filepath = os.path.join(tmpdir, "data.txt")
with open(filepath, "w") as f:
f.write("临时数据")
# 退出with块后,临时目录自动删除9.2 递归删除目录
python
import os
import shutil
# 删除整个目录(包括非空目录)
shutil.rmtree("data")
# os模块没有直接提供这个功能,需要用shutil9.3 获取文件大小
python
import os
def get_size(path):
"""获取文件或目录的大小"""
if os.path.isfile(path):
return os.path.getsize(path)
elif os.path.isdir(path):
total = 0
for root, dirs, files in os.walk(path):
for f in files:
filepath = os.path.join(root, f)
total += os.path.getsize(filepath)
return total
return 0十、总结
os模块是Python和操作系统之间的桥梁:
| 分类 | 常用函数/属性 |
|---|---|
| 环境变量 | environ, getenv() |
| 工作目录 | getcwd(), chdir() |
| 目录操作 | mkdir(), makedirs(), listdir(), walk(), scandir() |
| 文件操作 | remove(), rename(), stat(), chmod(), link(), symlink() |
| 系统命令 | system(), popen() |
| 系统常量 | sep, linesep, name, devnull |
| 进程信息 | getpid(), getppid(), getlogin() |
os模块的函数很多,不用全记住。最常用的就是os.path(下一章单独讲)、os.environ、os.listdir()、os.makedirs()这几个。遇到具体需求时查文档就行。